package tech.aistar.aop;


import jakarta.servlet.http.HttpServletRequest;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import tech.aistar.anno.FormToken;
import tech.aistar.exception.FormTokenException;

import java.util.UUID;

@Component
@Aspect
public class FormTokenAop {

    @Autowired
    private RedisTemplate redisTemplate;

    @Before("@annotation(formToken)")
    public void check(JoinPoint joinPoint, FormToken formToken) throws FormTokenException {
        //在非控制层的地方
        ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest req = sra.getRequest();
        if (formToken.create()) {
            //① 负责在server端创建token,并且存储到session
            String token = UUID.randomUUID().toString();

            redisTemplate.opsForValue().set("serverToken", token);

            System.out.println("serverToken已经创建好了!");
        }
        //② 判断是否是重复提交
        if(formToken.repeat()){
            //1. 先从session中获取serverToken,看是否是存在的
            if(isRepeat(req)){
                //说明是重复提交...
                //抛出去异常...
                throw new FormTokenException("sorry,重复提交了!");
            }else{
                //正常执行我们的业务...
                System.out.println("第一次进来执行~");
                //req.getSession().removeAttribute("serverToken");
                //redis删除key
                redisTemplate.delete("serverToken");
            }
        }
    }

    public boolean isRepeat(HttpServletRequest req){
        //String token = (String) req.getSession().getAttribute("serverToken");

        if(!redisTemplate.hasKey("serverToken"))
            return true;
        return false;
    }
}
